package com.photoeditor.demo.ui.widget.image.hair;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BlurMaskFilter;
import android.graphics.BlurMaskFilter.Blur;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.CornerPathEffect;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.PointF;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.widget.ImageView;

import com.android.gpuimage.GPUImage;
import com.android.gpuimage.GPUImageFilter;
import com.android.gpuimage.GPUImageFilterGroup;
import com.android.gpuimage.GPUImageGrayLightFilter;
import com.android.gpuimage.GPUImageSoftLightColorBlendFilter;
import com.photoeditor.demo.util.AsyncTask;

import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

public class Color_view extends ImageView implements OnSeekBarChangeListener {

    private float mDefaultScale;
    private Matrix mDefaultMatrix;

    private float mStokenSize;//绘制的stoken size
    private float mCircleSize;//触碰时圆的大小
    private float mDistanceTouchSize;//distance绘制的时候触碰位置的大小
    private float mRadiusDistance;//两个圆的半径 * 2开根号
    private float mDistanceWithTouch;//操作位置和实际绘制位置的距离
    private float f1629I;
    private float mCurrentScale;//当前的缩放值  不包含初始缩放
    private float f1631K;
    private boolean mIsDrawing;//是否正在绘制
    private boolean mPantingEnable;//当前是否可以绘制
    boolean mIsDown;//是否按下了
    boolean mIsTouch;//是否触碰
    float mTouchX;//触碰点的X值
    float mTouchY;//触碰点的Y值
    Matrix mOppMatrix;//操作的Matrix
    Matrix mCacheMatrix;//缓存的Matrix
    int mPointFlags;//就是一个标识
    PointF mCenterPoint;//用于缩放时存储重点点
    float mDefaultSpacing;//缩放时默认的间距
    float mPostScale;//缩放值

    private Canvas mOperationCanvas;//绘制的Canvas
    private Canvas mDrawCanvas;//绘制的Canvas
    private Bitmap mHighQualityOriginalBitmap;//高质量的原图
    private Bitmap mOriginalBitmap;//原图
    private Bitmap mFilterBitmap;//处理后的效果图
    private Bitmap mOperationBitmap;//绘制的Bitmap + 原图的结果
    private Bitmap mDrawBitmap;//绘制Bitmap的复制

    private Bitmap mFilterBitmapClone;//处理后的效果图的Clone


    private Paint mOperationPaint;//绘制的Paint
    private Paint mSrcInPaint;//src_in的Paint
    private Paint mDistanceTouchInterPaint;//distance绘制时的操作按钮内环的Paint
    private Paint mDistanceCirclePaint;//distance绘制时的实际绘制圆的Paint
    private Paint mDistanceTouchPaint;//distance绘制时的操作按钮的Paint
    private Paint mCommonPaint;//用于绘制FilterBitmap
    private Paint mCanvasPaint;//Dst_Out 用于绘制DrawBitmap

    private Path mPath;//绘制的Path
    private boolean mDistanceTouch;//是否是距离涂鸦
    private float[] mBound;//用于存储left top right bottom

    private float[] mCurrentColor;//当前的颜色值
    private boolean mIsCreate;

    private Stack<IDrawOperation> mHistoryPath;
    private boolean mHasPaint;
    private IStrokenChangeListener mStrokenChangeListener;

    private boolean mShowOriginalBitmap;


    public Color_view(Context context) {
        this(context, null);
    }

    public Color_view(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        mHistoryPath = new Stack<>();
        mIsDown = false;
        mDistanceTouch = false;
//        f1638c = null;
        mIsTouch = false;
        mBound = new float[4];
        mTouchX = 0.0f;
        mTouchY = 0.0f;
        mDistanceWithTouch = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5.0f, getResources().getDisplayMetrics());
        mOppMatrix = new Matrix();
        mCacheMatrix = new Matrix();
        mDefaultMatrix = new Matrix();
        mPointFlags = 0;
        mCenterPoint = new PointF();
        mDefaultSpacing = 1.0f;
        mPostScale = 1.0f;
        mCurrentScale = 1.0f;
        mIsDrawing = false;
        mPantingEnable = true;
//        f1634N = -1;
        mCurrentColor = new float[4];
        mDefaultScale = 1.0f;
        setScaleType(ScaleType.FIT_CENTER);
        setCreate(false);
        mHasPaint = false;
        mShowOriginalBitmap = false;
    }

    public void create(Bitmap bitmap, int color) {
        reset();
        mHighQualityOriginalBitmap = bitmap;
        bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 2, bitmap.getHeight() / 2, true);
        setImageBitmap(bitmap);
        mStokenSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 12.5f, getResources().getDisplayMetrics());
        mCircleSize = mStokenSize + (mStokenSize / 4.0f);
        mDistanceTouchSize = mCircleSize / 3.0f;
        mRadiusDistance = ((mCircleSize / 2.0f) + (mDistanceTouchSize / 2.0f)) * (float) Math.sqrt(2.0f);
        try {
            mOriginalBitmap = bitmap.copy(Config.ARGB_8888, true);
            mOperationBitmap = bitmap.copy(Config.ARGB_8888, true);
            mDrawBitmap = bitmap.copy(Config.ARGB_8888, true);
            mOperationCanvas = new Canvas(mOperationBitmap);
            mDrawCanvas = new Canvas(mDrawBitmap);
            if (mPath == null) {
                mPath = new Path();
            } else {
                mPath.reset();
            }
            if (mOperationPaint == null) {
                mOperationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            mOperationPaint.setStyle(Style.STROKE);
            mOperationPaint.setStrokeWidth(mStokenSize / mDefaultScale);
            mOperationPaint.setDither(true);
            mOperationPaint.setMaskFilter(new BlurMaskFilter(mStokenSize / 4.0f, Blur.NORMAL));
            mOperationPaint.setColor(-65536);
            mOperationPaint.setStrokeCap(Cap.ROUND);
            mOperationPaint.setPathEffect(new CornerPathEffect(10.0f));
            mOperationPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));

            if (mSrcInPaint == null) {
                mSrcInPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            mSrcInPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
            mSrcInPaint.setDither(true);
            mSrcInPaint.setFilterBitmap(true);

            if (mDistanceTouchInterPaint == null) {
                mDistanceTouchInterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            mDistanceTouchInterPaint.setStyle(Style.STROKE);
            mDistanceTouchInterPaint.setStrokeWidth(1.0f);
            mDistanceTouchInterPaint.setDither(true);
            mDistanceTouchInterPaint.setStrokeJoin(Join.ROUND);
            mDistanceTouchInterPaint.setColor(-1);

            if (mDistanceCirclePaint == null) {
                mDistanceCirclePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            mDistanceCirclePaint.setStyle(Style.STROKE);
            mDistanceCirclePaint.setStrokeWidth(1.0f);
            mDistanceCirclePaint.setDither(true);
            mDistanceCirclePaint.setStrokeJoin(Join.ROUND);
            mDistanceCirclePaint.setColor(-16777216);

            if (mDistanceTouchPaint == null) {
                mDistanceTouchPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            mDistanceTouchPaint.setStyle(Style.FILL_AND_STROKE);
            mDistanceTouchPaint.setStrokeWidth(1.0f);
            mDistanceTouchPaint.setDither(true);
            mDistanceTouchPaint.setStrokeJoin(Join.ROUND);
            mDistanceTouchPaint.setColor(-65536);

            if (mCommonPaint == null) {
                mCommonPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            mCommonPaint.setDither(true);
            mCommonPaint.setFilterBitmap(true);
            mOppMatrix.set(getImageMatrix());

            if (mCanvasPaint == null) {
                mCanvasPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            }
            mCanvasPaint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));

            int red = Color.red(color);
            int green = Color.green(color);
            int blue = Color.blue(color);
            int alpha = Color.alpha(color);
            mCurrentColor[0] = red / 255f;
            mCurrentColor[1] = green / 255f;
            mCurrentColor[2] = blue / 255f;
            mCurrentColor[3] = alpha / 255f;
            setPantingEnable(false);
            getFilterBitmap(mOriginalBitmap, mCurrentColor, new GPUImage.ResponseListener<Bitmap>() {
                @Override
                public void response(final Bitmap item) {
                    post(new Runnable() {
                        @Override
                        public void run() {
                            setCreate(true);
                            mFilterBitmap = item;
                            setPantingEnable(true);
                            invalidate();
                        }
                    });
                }
            });
        } catch (Throwable e) {
        }
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mBound[0] = 0.0f;
        mBound[1] = 0.0f;
        mBound[2] = (float) getWidth();
        mBound[3] = (float) getHeight();
        getImageMatrix().mapPoints(mBound);
        if (!isCreate()) return;
        if (mShowOriginalBitmap) return;
        int saveFlags = canvas.saveLayer(0, 0, getWidth(), getHeight(), null, Canvas.ALL_SAVE_FLAG);
        if (mOperationBitmap != null && mIsTouch) {
            mOperationCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
            mOperationCanvas.drawBitmap(mDrawBitmap, 0.0f, 0.0f, null);
            mOperationCanvas.drawPath(mPath, mOperationPaint);
//            mOperationCanvas.drawBitmap(mOriginalBitmap, 0.0f, 0.0f, mSrcInPaint);
            canvas.drawBitmap(mFilterBitmap, mOppMatrix, mCommonPaint);
            canvas.drawBitmap(mOperationBitmap, mOppMatrix, mCanvasPaint);
            if (!mIsDown || !mPantingEnable) {
                return;
            }
            if (mDistanceTouch) {
                canvas.drawCircle(mTouchX, mTouchY, mDistanceTouchSize / 2.0f, mDistanceTouchPaint);
                canvas.drawCircle((mTouchX - (mRadiusDistance / 2.0f)) - mDistanceWithTouch, (mTouchY - (mRadiusDistance / 2.0f)) - mDistanceWithTouch, mCircleSize / 2.0f, mDistanceTouchInterPaint);
                canvas.drawCircle((mTouchX - (mRadiusDistance / 2.0f)) - mDistanceWithTouch, (mTouchY - (mRadiusDistance / 2.0f)) - mDistanceWithTouch, (mCircleSize / 2.0f) + 2.0f, mDistanceCirclePaint);
                return;
            }
            canvas.drawCircle(mTouchX, mTouchY, mCircleSize / 2.0f, mDistanceTouchInterPaint);
        }
        canvas.restoreToCount(saveFlags);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed) {
            countDefaultScale();
        }
    }

    /**
     * 计算默认的缩放值
     */
    private void countDefaultScale() {
        if (mOriginalBitmap == null) {
            mDefaultScale = 1.0f;
            return;
        }
        float width = getWidth();
        float height = getHeight();
        float bw = mOriginalBitmap.getWidth();
        float bh = mOriginalBitmap.getHeight();
        if (bw / bh > width / height) {//图片比较宽
            mDefaultScale = width / bw;
        } else {
            mDefaultScale = height / bh;
        }
        setBrushSize(mStokenSize);
        countSupportMatrix();
    }

    /**
     * 初始化SupportMatrix
     */
    private void countSupportMatrix() {
        mDefaultMatrix.reset();
        float bw = mOriginalBitmap.getWidth();
        float bh = mOriginalBitmap.getHeight();
        float viewW = getWidth();
        float viewH = getHeight();
        mDefaultMatrix.setRectToRect(new RectF(0, 0, bw, bh), new RectF(0, 0, viewW, viewH), Matrix.ScaleToFit.CENTER);
    }

    public boolean onTouchEvent(MotionEvent motionEvent) {
        float x;
        float width;
        if (getScaleType() != ScaleType.MATRIX) {
            setScaleType(ScaleType.MATRIX);
        }
        mIsTouch = true;
        Matrix matrix = getImageMatrix();
        mOppMatrix.set(matrix);
        if (mDistanceTouch) {
            x = motionEvent.getX();
            mTouchX = x;
            width = ((float) getWidth()) * ((((x - (mRadiusDistance / 2.0f)) - mDistanceWithTouch) - mBound[0]) / (mBound[2] - mBound[0]));
            x = motionEvent.getY();
            mTouchY = x;
            x = ((((x - (mRadiusDistance / 2.0f)) - mDistanceWithTouch) - mBound[1]) / (mBound[3] - mBound[1])) * ((float) getHeight());
        } else {
            x = motionEvent.getX();
            mTouchX = x;
            width = ((float) getWidth()) * ((x - mBound[0]) / (mBound[2] - mBound[0]));
            x = motionEvent.getY();
            mTouchY = x;
            x = ((x - mBound[1]) / (mBound[3] - mBound[1])) * ((float) getHeight());
        }
        switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN /*0*/:
                mCacheMatrix.set(mOppMatrix);
                mIsDown = true;
                mHasPaint = false;
                f1629I = width;
                f1631K = x;
                mPath.moveTo(width, x);
                invalidate();
                break;
            case MotionEvent.ACTION_UP /*1*/:
                if (mIsDown && mPantingEnable && mHasPaint) {
                    mHistoryPath.push(new DrawOperation(mPath, new Paint(mOperationPaint)));
                    invokeChange(mHistoryPath.size());
                    mHasPaint = false;
                }

                //将没有绘制完的部分绘制到mOperationBitmap上
                mOperationCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
                mOperationCanvas.drawBitmap(mDrawBitmap, 0.0f, 0.0f, null);
                mOperationCanvas.drawPath(mPath, mOperationPaint);
//                mOperationCanvas.drawBitmap(mOriginalBitmap, 0.0f, 0.0f, mSrcInPaint);//这句其实没有用

                mDrawCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
                mDrawCanvas.drawBitmap(mOperationBitmap, 0, 0, mCommonPaint);
                mPath = new Path();

                mPointFlags = 0;
                mIsDown = false;
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE /*2*/:
                if (mPointFlags != 1 && mPointFlags != 2) {
                    if (mPointFlags != 3 && mPantingEnable) {
                        if (!(f1629I == 0.0f || f1631K == 0.0f)) {
                            float abs = Math.abs(width - f1629I);
                            float abs2 = Math.abs(x - f1631K);
                            if (abs >= 4.0f || abs2 >= 4.0f) {
                                mPath.quadTo(f1629I, f1631K, (f1629I + width) / 2.0f, (f1631K + x) / 2.0f);
                                f1629I = width;
                                f1631K = x;
                                mIsDrawing = true;
                                mHasPaint = true;
                            }
                        }
                        invalidate();
                    }
                    break;
                }
                mOppMatrix.set(mCacheMatrix);
                PointF pointF = new PointF();
                if (motionEvent.getPointerCount() >= 2) {
                    centerPoint(pointF, motionEvent);
                    mOppMatrix.postTranslate(pointF.x - mCenterPoint.x, pointF.y - mCenterPoint.y);
                    x = spacing(motionEvent);
                    if (x > 5.0f) {
                        x /= mDefaultSpacing;
                        if (mCurrentScale <= 15.0f && mCurrentScale >= 0.5f) {
                            if (mCurrentScale * x > 15.0f) {
                                x = 15.0f / mCurrentScale;
                            } else if (mCurrentScale * x < 0.5f) {
                                x = 0.5f / mCurrentScale;
                            }
                            mOppMatrix.postScale(x, x, mCenterPoint.x, mCenterPoint.y);
                            mPostScale = x;
                            break;
                        }
                    }
                }
                break;
            case MotionEvent.ACTION_POINTER_DOWN /*5*/:
//                mDrawBitmap.recycle();
//                mDrawBitmap = null;
//                mDrawBitmap = mOperationBitmap.copy(Config.ARGB_8888, true);
                if (mIsDown && mPantingEnable && mHasPaint) {
                    mHistoryPath.push(new DrawOperation(mPath, new Paint(mOperationPaint)));
                    invokeChange(mHistoryPath.size());
                    mHasPaint = false;
                }

                mDrawCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
                mDrawCanvas.drawBitmap(mOperationBitmap, 0, 0, mCommonPaint);
                mPath = new Path();
                if (motionEvent.getPointerCount() >= 2) {
                    mDefaultSpacing = spacing(motionEvent);
                    mIsDown = false;
                    mCacheMatrix.set(mOppMatrix);
                    centerPoint(mCenterPoint, motionEvent);
                    mPointFlags = 2;
                    invalidate();
                    break;
                }
                break;
            case MotionEvent.ACTION_POINTER_UP:
                setBrushSize(mStokenSize / mPostScale);
                mCurrentScale *= mPostScale;
                if (mCurrentScale > 15.0f) {
                    mCurrentScale = 15.0f;
                } else if (mCurrentScale < 0.5f) {
                    mCurrentScale = 0.5f;
                }
                mPostScale = 1.0f;
                mPointFlags = 3;
                break;
        }
        setImageMatrix(mOppMatrix);
        return true;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent motionEvent) {
        try {
            return super.dispatchTouchEvent(motionEvent);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * @param motionEvent
     * @return
     */
    private float spacing(MotionEvent motionEvent) {
        float x = motionEvent.getX(0) - motionEvent.getX(1);
        float y = motionEvent.getY(0) - motionEvent.getY(1);
        return (float) Math.sqrt((x * x) + (y * y));
    }

    /**
     * 计算中间点坐标存储到pointF中
     *
     * @param pointF
     * @param motionEvent
     */
    private void centerPoint(PointF pointF, MotionEvent motionEvent) {
        pointF.set((motionEvent.getX(0) + motionEvent.getX(1)) / 2.0f, (motionEvent.getY(0) + motionEvent.getY(1)) / 2.0f);
    }

    /**
     * 设置图片的饱和度
     *
     * @param bitmap
     * @param i      饱和度的值
     * @return
     */
    private Bitmap setBitmapSaturation(Bitmap bitmap, int i) {
        Bitmap createBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(createBitmap);
        Paint paint = new Paint();
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.setSaturation((float) i);
        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
        canvas.drawBitmap(bitmap, 0.0f, 0.0f, paint);
        return createBitmap;
    }

//
//
//
//
//    public void m2325c() {
//        if (mIsDrawing) {
//            mDrawBitmap = mOperationBitmap.copy(Config.ARGB_8888, true);
//            mPath.reset();
//            mIsDrawing = false;
//        }
//        f1653r = mDrawBitmap.copy(Config.ARGB_8888, true);
//    }
//
//    public void m2320a(int i) {
//        f1634N = i;
//        f1635O = false;
//        String[] split = HorizontalImageAdapterSubColors.f1786e[i].split(",");
//        if (f1642g != null) {
//            mFilterBitmap = Bitmap.createBitmap(ApplyFilters.applySoftLight((int[]) f1642g.clone(), Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2])), mFilterBitmap.getWidth(), mFilterBitmap.getHeight(), Config.ARGB_8888);
//            mFilterBitmapClone = mFilterBitmap.copy(Config.ARGB_8888, true);
//            invalidate();
//        }
//    }
//
//    public void m2324b(int i) {
//        f1634N = i;
//        f1635O = true;
//        if (f1642g != null) {
//            mFilterBitmap = Bitmap.createBitmap(ApplyFilters.applySoftLight((int[]) f1642g.clone(), Color.red(Integer.parseInt((String) ShareUtil.m630b().m631a().get(i))), Color.green(Integer.parseInt((String) ShareUtil.m630b().m631a().get(i))), Color.blue(Integer.parseInt((String) ShareUtil.m630b().m631a().get(i)))), mFilterBitmap.getWidth(), mFilterBitmap.getHeight(), Config.ARGB_8888);
//            mFilterBitmapClone = mFilterBitmap.copy(Config.ARGB_8888, true);
//            invalidate();
//        }
//    }

    /**
     * 生成最终的图片
     *
     * @param highQuality
     * @return
     */
    public Bitmap getFinalResult(boolean highQuality) {
        if (highQuality) {
            Bitmap filterBitmap = GPUImage.getBitmapForFilter(mHighQualityOriginalBitmap, createFilter(mCurrentColor));
            try {
                float scale = ((float) filterBitmap.getWidth()) / ((float) mOperationBitmap.getWidth());
                Matrix matrix2 = new Matrix();
                matrix2.setScale(scale, scale);
                Canvas canvas = new Canvas(filterBitmap);
                canvas.drawBitmap(filterBitmap, 0.0f, 0.0f, mCommonPaint);
                canvas.save();
                Bitmap createBitmap = Bitmap.createBitmap(filterBitmap.getWidth(), filterBitmap.getHeight(), Config.ARGB_8888);
                Canvas canvas2 = new Canvas(createBitmap);
                canvas2.drawBitmap(mOperationBitmap, matrix2, mCommonPaint);
                canvas2.drawBitmap(mHighQualityOriginalBitmap, 0.0f, 0.0f, mSrcInPaint);
                canvas.drawBitmap(createBitmap, 0.0f, 0.0f, mCommonPaint);
                canvas.restore();
                createBitmap.recycle();
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return filterBitmap;
        } else {
            Bitmap createBitmap = Bitmap.createBitmap(mFilterBitmap.getWidth(), mFilterBitmap.getHeight(), Config.ARGB_8888);
            Canvas canvas = new Canvas(createBitmap);
            canvas.drawBitmap(mFilterBitmap, 0.0f, 0.0f, null);
            canvas.drawBitmap(mOperationBitmap, 0.0f, 0.0f, null);
            return createBitmap;
        }
    }

    /**
     * 设置为DistanceTouch模式
     *
     * @param distanceTouch
     */
    public void setDistanceYouch(boolean distanceTouch) {
        mDistanceTouch = distanceTouch;
    }

    /**
     * 这个方法用于异步获取bitmap的效果图
     *
     * @param bitmap
     */
    private void getFilterBitmap(final Bitmap bitmap, final float[] currentColor, final GPUImage.ResponseListener<Bitmap> listener) {
        new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                GPUImage.getBitmapForMultipleFilters(null, bitmap, createFilterList(currentColor), listener);
                return null;
            }

            @Override
            protected void onPostExecute(Void vo) {
                super.onPostExecute(vo);
            }
        }.execute();
    }

    /**
     * 生成FilterList
     *
     * @return
     */
    private List<GPUImageFilter> createFilterList(float color[]) {
        List<GPUImageFilter> filters = new ArrayList<>();
        GPUImageGrayLightFilter gpuImageGrayLightFilter = new GPUImageGrayLightFilter();
        GPUImageSoftLightColorBlendFilter gpuImageSoftLightColorBlendFilter = new GPUImageSoftLightColorBlendFilter(color);
        GPUImageFilterGroup filterGroup = new GPUImageFilterGroup();
        filterGroup.addFilter(gpuImageGrayLightFilter);
        filterGroup.addFilter(gpuImageSoftLightColorBlendFilter);
        filters.add(filterGroup);
        return filters;
    }

    /**
     * 生成Filter
     *
     * @return
     */
    private GPUImageFilter createFilter(float color[]) {
        GPUImageGrayLightFilter gpuImageGrayLightFilter = new GPUImageGrayLightFilter();
        GPUImageSoftLightColorBlendFilter gpuImageSoftLightColorBlendFilter = new GPUImageSoftLightColorBlendFilter(color);
        GPUImageFilterGroup filterGroup = new GPUImageFilterGroup();
        filterGroup.addFilter(gpuImageGrayLightFilter);
        filterGroup.addFilter(gpuImageSoftLightColorBlendFilter);
        return filterGroup;
    }


    /**
     * 设置橡皮叉大小
     *
     * @param f
     */
    private void setBrushSize(float f) {
        mStokenSize = f;
        if (mOperationPaint != null) {
            mOperationPaint.setStrokeWidth(mStokenSize / mDefaultScale);
            mOperationPaint.setMaskFilter(new BlurMaskFilter(mStokenSize / 4.0f, Blur.NORMAL));
        }
    }

    /**
     * 用于修改画笔或者橡皮擦大小
     *
     * @param progress 0-100  ---> 1-24
     */
    public void setBrushProgress(int progress) {
        float applyDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) ((progress / 100f) * 23 + 1), getResources().getDisplayMetrics());
        setBrushSize(applyDimension / mCurrentScale);
        mCircleSize = applyDimension + (applyDimension / 4.0f);
        mRadiusDistance = ((mCircleSize / 2.0f) + (mDistanceTouchSize / 2.0f)) * (float) Math.sqrt(2.0f);
    }

    /**
     * 用于有间距涂时的间距大小设置
     *
     * @param progress 0-100
     */
    public void setDistanceTouchWidth(int progress) {
        mDistanceWithTouch = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) (progress + 5), getResources().getDisplayMetrics());
    }

    /**
     * 设置当前是否能涂
     *
     * @param enable
     */
    public void setPantingEnable(boolean enable) {
        mPantingEnable = enable;
    }

    /**
     * 这里是使用了颜色矩阵, 根据矩阵相乘的理论,
     * a1, a2, a3, a4, a5;       a1*R + a2*G + a3*B + a4*A + a5 = R1
     * b1, b2, b3, b4, b5;       b1*R + b2*G + b3*B + b4*A + b5 = G1
     * c1, c2, c3, c4, c5;       c1*R + c2*G + c3*B + c4*A + c5 = B1
     * d1, d2, d3, d4, d5;       d1*R + d2*G + d3*B + d4*A + d5 = A1
     *
     * @param bitmap
     * @param i
     * @return
     */
    public Bitmap setBitmapColorFilter(Bitmap bitmap, int i) {
        Bitmap createBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
        int i2 = i - 127;
        ColorMatrix colorMatrix = new ColorMatrix();
        colorMatrix.set(new float[]{1.0f, 0.0f, 0.0f, 0.0f, (float) i2, 0.0f, 1.0f, 0.0f, 0.0f, (float) i2, 0.0f, 0.0f, 1.0f, 0.0f, (float) i2, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f});
        Paint paint = new Paint();
        paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
        new Canvas(createBitmap).drawBitmap(bitmap, 0.0f, 0.0f, paint);
        return createBitmap;
    }

    /**
     * 设置图片的饱和度
     *
     * @param bitmap
     * @param progress 进度
     * @return
     */
    public Bitmap setHairSaturation(Bitmap bitmap, int progress) {
        Bitmap createBitmap;
        synchronized (bitmap) {
            ColorMatrix colorMatrix = new ColorMatrix();
            ColorFilter colorMatrixColorFilter = new ColorMatrixColorFilter(colorMatrix);
            Paint paint = new Paint();
            paint.setColorFilter(colorMatrixColorFilter);
            createBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Config.ARGB_8888);
            colorMatrix.setSaturation(((float) progress) / 50.0f);
            Canvas canvas = new Canvas(createBitmap);
            paint.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
            canvas.drawBitmap(bitmap, 0.0f, 0.0f, paint);
        }
        return createBitmap;
    }

    /**
     * 切换到绘制
     */
    public void switchToDraw() {
        if (mOperationBitmap != null) {
            mDrawCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
            mDrawCanvas.drawBitmap(mOperationBitmap, 0, 0, mCommonPaint);
//            mDrawBitmap = mOperationBitmap.copy(Config.ARGB_8888, true);
            mPath.reset();
            mOperationPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
        }
    }

    /**
     * 切换到橡皮擦
     */
    public void switchToErase() {
        if (mOperationBitmap != null) {
            mDrawCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
            mDrawCanvas.drawBitmap(mOperationBitmap, 0, 0, mCommonPaint);
//            mDrawBitmap = mOperationBitmap.copy(Config.ARGB_8888, true);
            mPath.reset();
            mOperationPaint.setXfermode(null);
        }
    }

    /**
     * 生成FilterBitmap的克隆
     *
     * @return
     */
    private Bitmap makeFilterBitmapClone() {
        if (mFilterBitmapClone != null) {
            return mFilterBitmapClone;
        }
        if (mFilterBitmap == null) {
            return null;
        }
        Bitmap copy = mFilterBitmap.copy(Config.ARGB_8888, true);
        mFilterBitmapClone = copy;
        return copy;
    }

    /**
     * 修改颜色
     *
     * @param newColor 按照RGBA的顺序
     */
    public void changeColor(float[] newColor) {
        if (newColor == null || newColor.length != 4) return;
        mCurrentColor[0] = newColor[0];
        mCurrentColor[1] = newColor[1];
        mCurrentColor[2] = newColor[2];
        mCurrentColor[3] = newColor[3];
        setPantingEnable(false);
        getFilterBitmap(mOriginalBitmap, mCurrentColor, new GPUImage.ResponseListener<Bitmap>() {
            @Override
            public void response(final Bitmap item) {
                post(new Runnable() {
                    @Override
                    public void run() {
                        mFilterBitmap = item;
                        setPantingEnable(true);
                        invalidate();
                    }
                });
            }
        });
    }

    /**
     * 修改颜色
     *
     * @param color
     */
    public void changeColor(int color) {
        int red = Color.red(color);
        int green = Color.green(color);
        int blue = Color.blue(color);
        int alpha = Color.alpha(color);
        changeColor(new float[]{((float) red) / 255, ((float) green) / 255, ((float) blue) / 255, ((float) alpha) / 255});
    }

    public boolean isCreate() {
        return mIsCreate;
    }

    public void setCreate(boolean mCreate) {
        mIsCreate = mCreate;
    }

    public void reset() {
        mCurrentScale = 1.0f;
        mIsDown = false;
        mDistanceTouch = false;
        mIsTouch = false;
        mBound = new float[4];
        mTouchX = 0.0f;
        mTouchY = 0.0f;
        mDistanceWithTouch = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5.0f, getResources().getDisplayMetrics());
        mPointFlags = 0;
        mCenterPoint = new PointF();
        mDefaultSpacing = 1.0f;
        mPostScale = 1.0f;
        mCurrentScale = 1.0f;
        mIsDrawing = false;
        mPantingEnable = true;
        setImageMatrix(mDefaultMatrix);
        mOppMatrix.set(mDefaultMatrix);
        mCacheMatrix.set(mOppMatrix);
        setCreate(false);
        mHistoryPath.clear();
        mShowOriginalBitmap = false;
    }


    public void onProgressChanged(CustomSizeSeekBar seekBar, int i, boolean z) {
//        float applyDimension = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) (i + 5), getResources().getDisplayMetrics());
//        if (seekBar.getId() == R.id.dist_seek) {
//            mDistanceWithTouch = applyDimension;
//        } else if (seekBar.getId() == R.id.vertical_Seekbar) {
//            setBrushSize(applyDimension / mCurrentScale);
//            mCircleSize = applyDimension + (applyDimension / 4.0f);
//            mRadiusDistance = ((mCircleSize / 2.0f) + (mDistanceTouchSize / 2.0f)) * (float)Math.sqrt(2.0f);
//        }
        setBrushProgress(i);
    }

    public void onStartTrackingTouch(CustomSizeSeekBar seekBar) {
        if (mIsDrawing) {
            mDrawCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);
            mDrawCanvas.drawBitmap(mOperationBitmap, 0, 0, mCommonPaint);
//            mDrawBitmap = mOperationBitmap.copy(Config.ARGB_8888, true);
            mPath.reset();
            mIsDrawing = false;
        }
    }

    public void onStopTrackingTouch(CustomSizeSeekBar seekBar) {
//        if (seekBar.getId() == R.id.smooth_seek) {
//            mDrawBitmap = Bitmap.createBitmap(Blur.m2386a(f1653r, seekBar.getProgress() + 1), 0, 0, f1653r.getWidth(), f1653r.getHeight());
//        } else if (seekBar.getId() == R.id.color_seek) {
//            if (makeFilterBitmapClone() != null) {
//                mFilterBitmap = setHairSaturation(mFilterBitmapClone, seekBar.getProgress());
//                mFilterBitmap = setBitmapColorFilter(mFilterBitmap, ((SeekBar) ((Activity) getContext()).findViewById(R.id.bright_seek)).getProgress() + 103);
//            } else {
//                return;
//            }
//        } else if (seekBar.getId() == R.id.bright_seek) {
//            if (makeFilterBitmapClone() != null) {
//                mFilterBitmap = setHairSaturation(mFilterBitmapClone, ((SeekBar) ((Activity) getContext()).findViewById(R.id.color_seek)).getProgress());
//                mFilterBitmap = setBitmapColorFilter(mFilterBitmap, seekBar.getProgress() + 103);
//            } else {
//                return;
//            }
//        }
//        invalidate();
    }

    /**
     * 回退上一步
     */
    public void undo() {
        if (mOperationBitmap != null && mHistoryPath.size() > 0) {
            mHistoryPath.pop();//弹掉一个
            int size = mHistoryPath.size();
            invokeChange(size);
            if (size > 0) {
                mDrawCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);//清除数据
                mDrawCanvas.drawBitmap(mOriginalBitmap, 0, 0, mCommonPaint);
                for (IDrawOperation nextOperation : mHistoryPath) {
                    nextOperation.operation(mDrawCanvas);
                }
            } else {
                mDrawCanvas.drawColor(Color.TRANSPARENT, Mode.CLEAR);//清除数据
                mDrawCanvas.drawBitmap(mOriginalBitmap, 0, 0, mCommonPaint);
            }
            mPath.reset();
            invalidate();
        }
    }

    /**
     * 是否有绘制
     *
     * @return true则是有绘制  false是没有绘制
     */
    public boolean isChanged() {
        return (mHistoryPath.size() != 0);
    }

    /**
     * 设置Stroken chang的监听器  mHistoryPath大小改变的时候就会回调
     *
     * @param mStrokenChangeListener
     */
    public void setStrokenChangeListener(IStrokenChangeListener mStrokenChangeListener) {
        this.mStrokenChangeListener = mStrokenChangeListener;
    }

    /**
     * 历史路径修改时回调
     *
     * @param size
     */
    private void invokeChange(int size) {
        if (mStrokenChangeListener != null) {
            mStrokenChangeListener.onStrokenSizeChanged(size);
        }
    }

    /**
     * 显示原图
     */
    public void showOriginalBitmap() {
        mShowOriginalBitmap = true;
        invalidate();
    }

    /**
     * 显示效果图
     */
    public void showEffect() {
        mShowOriginalBitmap = false;
        invalidate();
    }
}
